/*
 *
 *  *
 *  *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  *  SPDX-License-Identifier: Apache-2.0
 *  *
 *
 */

import React, { useCallback, useEffect, useMemo, useState } from 'react';
import PageBox from '@components/ui/PageBox';
import { Text, Form, Table, TableColumn, Bubble } from 'tea-component';
import liststyle from '../list.module.scss';
import detailstyle from '../detail.module.scss';
import { formatUnixTime } from '@src/utils/tools';
import { GetBlockDetail, GetTxList } from '@src/utils/apis';
import { BlockInfo, Tx } from '@src/models';
import { useParams } from 'react-router';
import { Link } from 'react-router-dom';
import SearchLink from '@src/components/form/SearchLink';
import { RootReducer } from '@src/store';
import { useSelector } from 'react-redux';

const { pageable, autotip } = Table.addons;
export default function BlockDetail() {
  const { blockHeight } = useParams();
  const { currentChain } = useSelector((state: RootReducer) => state.chainReducer);
  const chainId = useMemo(() => currentChain?.ChainId, [currentChain]);
  const authType = useMemo(() => currentChain?.AuthType, [currentChain]);
  const [detail, setDetail] = useState<BlockInfo | null>(null);
  const [list, setList] = useState<Tx[]>([]);
  const [pageIndex, setPageIndex] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(10);
  const [recordCount, setRecordCount] = useState(0);
  const [isLoading, setIsLoading] = useState(false);
  const getList = useCallback(() => {
    setIsLoading(true);
    GetTxList({
      ChainId: chainId,
      BlockHash: detail?.BlockHash,
      Limit: pageSize,
      Offset: pageIndex - 1,
    })
      .then((res) => {
        setIsLoading(false);
        if (res.GroupList) {
          setList(res.GroupList);
          setRecordCount(res.TotalCount);
        }
      })
      .catch(() => {
        setIsLoading(false);
      });
  }, [chainId, detail, pageIndex, pageSize]);
  const columns = useMemo<TableColumn<Tx>[]>(() => {
    const list: TableColumn<Tx>[] = [
      {
        key: 'BlockHeight',
        header: '区块高度',
        align: 'left',
        width: 100,
      },
      {
        key: 'TxId',
        header: '交易Id',
        align: 'left',
        width: 220,
        render: ({ TxId }) => <Link to={`/${chainId}/transaction/${TxId}`}>{TxId}</Link>,
      },
      {
        key: 'UserAddr',
        header: '发起用户',
        align: 'left',
        render:
          authType === 'permissionedwithcert'
            ? ({ Sender, UserAddr }) => <Bubble content={UserAddr}>{Sender}</Bubble>
            : undefined,
      },
      {
        key: 'ContractName',
        header: '目标合约',
        align: 'left',
        render: ({ ContractName }) => <Link to={`/${chainId}/contract/${ContractName}`}>{ContractName}</Link>,
      },
      {
        key: 'Status',
        header: '交易状态',
        align: 'left',
        width: 100,
        render: ({ Status }) => <Text theme={Status === 'SUCCESS' ? 'success' : 'danger'}>{Status}</Text>,
      },
      {
        key: 'Timestamp',
        header: '上链时间',
        align: 'left',
        render: ({ Timestamp }) => formatUnixTime(Timestamp),
        width: 180,
      },
      {
        key: 'Id',
        header: '操作',
        align: 'center',
        width: 100,
        render: ({ TxId }) => (
          <div className={liststyle.setting_c}>
            <Link to={`/${chainId}/transaction/${TxId}`}>查看</Link>
          </div>
        ),
      },
    ];
    if (authType === 'permissionedwithcert') {
      list.splice(1, 0, {
        key: 'SenderOrg',
        header: '发起组织',
        align: 'left',
      });
    }
    return list;
  }, []);
  useEffect(() => {
    GetBlockDetail({
      BlockHeight: blockHeight,
      ChainId: chainId,
    }).then((res) => {
      if (res.Data) {
        setDetail(res.Data);
      }
    });
  }, [chainId, blockHeight]);
  useEffect(() => {
    if (detail) {
      getList();
    }
  }, [pageIndex, detail, pageSize]);
  return (
    <PageBox title="区块详情">
      <div className={detailstyle.detail}>
        <Form.Title>区块基本信息</Form.Title>
        <Form hideLabel={false} fixedLabelWidth={110} layout="fixed">
          <Form.Item label="区块高度">
            <Form.Text>{detail?.BlockHeight}</Form.Text>
          </Form.Item>
          <Form.Item label="区块Hash">
            <Form.Text>{detail?.BlockHash || '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="前区块Hash">
            <Form.Text>{detail?.PreBlockHash ? <SearchLink>{detail.PreBlockHash}</SearchLink> : '--'}</Form.Text>
          </Form.Item>
          <Form.Item label="时间戳">
            <Form.Text>{detail?.Timestamp ? formatUnixTime(detail.Timestamp) : '--'}</Form.Text>
          </Form.Item>
        </Form>
        <Form.Title>其他信息</Form.Title>
        <Form hideLabel={false} fixedLabelWidth={110} layout="fixed">
          <Form.Item tips="对交易执行结果做哈希处理，并用于验证各节点的执行结果是否一致。" label="读写集哈希">
            <Form.Text>{detail?.RwSetHash || '--'}</Form.Text>
          </Form.Item>
          <Form.Item
            tips="将区块链的交易两两配对，依次向上递归合并计算哈希，直至只剩一个哈希值，该值即为交易的默克尔根。由于该默克尔根是由区块内全部的交易生成的，所以一旦其中一笔交易发生篡改，则最终默克尔根也会不同，所以可通过该特性检验区块数据是否被恶意篡改。"
            label="交易默克尔根"
          >
            <Form.Text>{detail?.TxRootHash || '--'}</Form.Text>
          </Form.Item>
          <Form.Item tips="将区块内的交易进行处理生成dag图，并根据确定好的dag图再生成对应的哈希。" label="DAG特征值">
            <Form.Text>{detail?.Dag || '--'}</Form.Text>
          </Form.Item>
          {authType === 'permissionedwithcert' && (
            <Form.Item label="出块组织">
              <Form.Text>{detail?.OrgId || '--'}</Form.Text>
            </Form.Item>
          )}
          <Form.Item label="出块节点">
            <Form.Text>
              <Bubble content={detail?.ProposalNodeAddr}> {detail?.ProposalNodeId || '--'}</Bubble>
            </Form.Text>
          </Form.Item>
        </Form>
        <Form.Title>交易信息</Form.Title>
      </div>
      <div className={liststyle.table}>
        <Table
          style={{
            marginTop: 24,
          }}
          className={liststyle.table}
          compact={false}
          records={list}
          recordKey="Id"
          bordered={true}
          disableTextOverflow={true}
          columns={columns}
          addons={[
            autotip({
              isLoading,
            }),
            pageable({
              recordCount,
              pageIndex,
              onPagingChange: (query) => {
                if (query?.pageIndex) {
                  setPageIndex(query.pageIndex);
                }
                if (query?.pageSize) {
                  setPageSize(query.pageSize);
                }
              },
            }),
          ]}
        />
      </div>
    </PageBox>
  );
}
